<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>雨珠特效</title>
    <style>
        body {
            position: relative;
            width: 100%;
            height: 100vh;
            margin: 0;
            overflow: hidden;
            background: #000;
        }

        #wrap-texture {
            position: relative;
            width: 100%;
            height: 100%;
        }

        #canvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        .plane {
            width: 100%;
            height: 100%;
        }

        .plane img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    </style>
</head>

<body>
    <div id="wrap-texture">
        <div id="canvas"></div>
        <div class="plane">
            <!-- 确保图片路径正确 -->
            <img src="./back.png" id="texture" alt="background">
        </div>
    </div>
</body>
<script src="https://www.curtainsjs.com/build/curtains.min.js"></script>
<script>
    window.onload = () => {
        const shader = {
            vertex: `
            #ifdef GL_ES
            precision mediump float;
            #endif

            attribute vec3 aVertexPosition;
            attribute vec2 aTextureCoord;
            uniform mat4 uMVMatrix;
            uniform mat4 uPMatrix;
            uniform mat4 dispImageMatrix;

            varying vec3 vVertexPosition;
            varying vec2 vTextureCoord;

            void main(){
                vec3 vertexPosition = aVertexPosition;
                gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0);
                vTextureCoord = aTextureCoord;
                vVertexPosition = vertexPosition;
            }`,
            fragment: `
            #ifdef GL_ES
            precision mediump float;
            #endif

            #define PI2 6.2831853
            #define PI 3.14159265359
            #define S(a,b,n) smoothstep(a,b,n)

            varying vec3 vVertexPosition;
            varying vec2 vTextureCoord;

            uniform float uTime;
            uniform vec2 uReso;
            uniform vec2 uMouse;
            uniform sampler2D dispImage;

            // 噪声
            float N12(vec2 p){
                p = fract(p * vec2(123.34,345.45));
                p += dot(p,p+34.345);
                return fract(p.x * p.y);
            }

            vec3 Layer(vec2 uv0,float t){
                vec2 asp = vec2(2.0,1.0);
                vec2 uv1 = uv0 * 3.0 * asp;

                uv1.y += t * 0.25;
                vec2 gv = fract(uv1) - .5;
                vec2 id = floor(uv1);
                float n = N12(id);
                t += n * PI2;
                float w = uv0.y * 10.0;
                float x = (n - 0.5) * 0.8;
                x += (0.4 - abs(x)) * sin(3.0 * w) * pow(sin(w),6.0) * 0.45;
                float y = -sin(t + sin(t + sin(t) * 0.5)) * 0.44;
                y -= (gv.x - x) * (gv.x - x);

                vec2 dropPos = (gv - vec2(x,y)) / asp;
                float drop = S(0.05,0.03,length(dropPos));
                
                vec2 TrialPos = (gv - vec2(x,t * 0.5)) / asp;
                TrialPos.y = (fract(TrialPos.y * 8.0) - 0.5) * 0.125;
                float Trial = S(0.1,0.05,length(TrialPos));
                
                float figTrial = S(-0.02,0.02,dropPos.y);
                float fogTrial = figTrial;

                fogTrial *= S(0.1,y,gv.y);
                Trial *= fogTrial;
                fogTrial *= S(0.05,0.02,abs(dropPos.x));

                vec2 off = drop * dropPos * 0.1 + Trial * TrialPos * 0.05;
                return vec3(off,fogTrial);
            }

            void main() {
                float dist = 2.0;
                float blurSize = 3.0;
                // 修复：使用非零时间因子
                float t = mod(uTime * 0.002, 7200.0);
                
                vec2 uv = vTextureCoord;
                vec3 drops = Layer(uv, t);
                drops += Layer(uv * 1.25 + 7.54, t + 10.0);
                drops += Layer(uv * 1.35 + 1.54, t + 20.0);
                drops += Layer(uv * 1.57 - 7.54, t + 30.0);

                float blur = blurSize * (1.0 - drops.z);
                vec4 col = vec4(0.0);
                int numSamples = 16; // 减少采样数提高性能
                float a = N12(uv) * PI2;

                blur *= 0.001;
                uv += drops.xy * dist;

                for(int n = 0; n < 16; n++){
                    float floatN = float(n);
                    vec2 off = vec2(sin(a), cos(a)) * blur;
                    float d = fract(sin((floatN + 1.0) * 546.0) * 5424.0);
                    d = sqrt(d);
                    off *= d;
                    col += texture2D(dispImage, uv + off);
                    a += 1.0;
                }
                
                col /= float(numSamples);
                gl_FragColor = col;
            }
            `
        };

        const canvasContainer = document.getElementById('canvas');
        const mouse = { x: 0, y: 0 };
        
        // 初始化 Curtains
        const webGLCurtain = new Curtains({ 
            container: "canvas",
            pixelRatio: Math.min(1.5, window.devicePixelRatio) // 优化性能
        });

        const planeElement = document.getElementsByClassName("plane")[0];

        const params = {
            vertexShader: shader.vertex,
            fragmentShader: shader.fragment,
            widthSegments: 20, // 减少分段数提高性能
            heightSegments: 20,
            uniforms: {
                time: {
                    name: 'uTime',
                    type: "1f",
                    value: 0
                },
                mousepos: {
                    name: "uMouse",
                    type: "2f",
                    value: [mouse.x, mouse.y]
                },
                resolution: {
                    name: "uReso",
                    type: "2f",
                    value: [window.innerWidth, window.innerHeight]
                }
            }
        };

        const plane = webGLCurtain.addPlane(planeElement, params);

        // 检查平面是否创建成功
        if(plane) {
            plane.onRender(() => {
                plane.uniforms.time.value += 1;
                plane.uniforms.resolution.value = [window.innerWidth, window.innerHeight];
            });

            canvasContainer.addEventListener("mousemove", (e) => {
                mouse.x = e.clientX;
                mouse.y = e.clientY;
                if(plane && plane.uniforms.mousepos) {
                    plane.uniforms.mousepos.value = [mouse.x, mouse.y];
                }
            });

            // 窗口大小改变时更新
            window.addEventListener("resize", () => {
                if(plane && plane.uniforms.resolution) {
                    plane.uniforms.resolution.value = [window.innerWidth, window.innerHeight];
                }
            });
        } else {
            console.error("Failed to create plane");
        }
    };
</script>

</html>